/*!
 * \file ObjectPool.hpp
 * \brief 对象池模板类，基于boost::pool实现高效的内存管理
 */
#pragma once
#include <boost/pool/pool.hpp>
#include <atomic>

/*!
 * \brief 对象池模板类
 * \tparam T 要管理的对象类型
 */
template < typename T>
class ObjectPool
{
	boost::pool<> _pool;	///< boost内存池对象

public:
	/// 构造函数，初始化内存池
	ObjectPool() :_pool(sizeof(T)) {}
	
	/// 虚析构函数
	virtual ~ObjectPool() {}

	/*!
	 * \brief 构造一个新对象
	 * 
	 * \details 从内存池中分配内存并调用对象的构造函数创建新实例。
	 *          这种方式避免了频繁的系统内存分配调用，提高了性能。
	 *          使用placement new在预分配的内存上构造对象，确保对象
	 *          的构造函数被正确调用，所有成员变量得到适当初始化。
	 *          
	 * \return 返回构造好的对象指针，如果内存分配失败则返回nullptr
	 * 
	 * \note 返回的对象指针必须使用destroy()方法释放，不能使用delete
	 * \warning 不要对返回的指针使用delete操作符，这会导致未定义行为
	 * 
	 * \see destroy(), release()
	 */
	T* construct()
	{
		void * mem = _pool.malloc();
		if (!mem)
			return nullptr;

		T* pobj = new(mem) T();
		return pobj;
	}

	/*!
	 * \brief 销毁对象并回收内存
	 * 
	 * \details 正确销毁由construct()方法创建的对象。首先调用对象的析构函数
	 *          释放对象内部资源，然后将内存归还给内存池以供重用。这种
	 *          两阶段销毁过程确保对象的清理工作得到正确执行，同时保持
	 *          内存池的完整性。内存不会立即返回给系统，而是保留在池中
	 *          以提高后续分配的性能。
	 *          
	 * \param pobj 要销毁的对象指针，必须是由construct()方法返回的有效指针
	 * 
	 * \note 传入的指针必须是由同一个ObjectPool实例的construct()方法创建
	 * \warning 不要传入nullptr或野指针，不要传入非本池创建的对象指针
	 * \warning 对象销毁后不要再次访问该指针，避免悬空指针问题
	 * 
	 * \see construct(), release()
	 */
	void destroy(T* pobj)
	{
		pobj->~T();
		_pool.free(pobj);
	}

	/*!
	 * \brief 手动释放未使用的内存
	 * 
	 * \details 将内存池中所有未分配的内存块归还给系统。这个操作会释放
	 *          池中缓存的空闲内存，减少程序的内存占用。已分配给对象的
	 *          内存不会被释放，只有通过destroy()归还到池中的空闲内存
	 *          才会被真正释放给系统。
	 *          
	 *          在内存压力较大或长期不需要创建新对象时调用此方法，
	 *          可以避免内存池无限制地缓存内存。但释放后的再次分配
	 *          可能需要重新向系统申请内存，会有一定的性能开销。
	 * 
	 * \note 此操作不影响已经分配给对象的内存
	 * \note 释放后的内存池仍然可以正常使用construct()创建新对象
	 * \warning 频繁调用此方法会影响内存池的性能优势
	 * 
	 * \see construct(), destroy()
	 */
	void release()
	{
		_pool.release_memory();
	}
}; 